#include <petscksp.h>
#include <jsoncpp/json/json.h>
#include <string>

#include "fem/wmanager.h"
#include "papcel/nnstokes3d.h"



struct CmdArguments {
public:

	std::string input_fname;

};


CmdArguments processCommandlineArgs(int argc, char **argv)
{
	CmdArguments cmd_args;
	cmd_args.input_fname = argv[1];

	return cmd_args;
}


int main(int argc, char **argv)
{
	PetscInitialize(&argc, &argv, (char *)0, "");

	CmdArguments args;
	Json::Reader reader(Json::Features::all());
	Json::Value  root;

	args = processCommandlineArgs(argc, argv);

	std::ifstream is(args.input_fname.c_str());
	bool parsing_successfull = reader.parse(is, root);
	if (!parsing_successfull)
	{
		printf("Error parsing input file '%s':\n%s\n", args.input_fname.c_str(), reader.getFormattedErrorMessages().c_str());
		exit(-1);
	}

	if (!root.isMember("problem"))
	{
		printf("Error: Missing key 'problem' in input file.\n");
		exit(-1);
	}

	const Json::Value problem = root["problem"];
	const char *problem_type = problem.get("type", "none").asString().c_str();
	CStateProblem *P;

	if (strcmp(problem_type,"NonNewtonianFlow3D") == 0)
	{
		P = new C3DNonNewtonianStokesProblem;
	}
	else
	{
		printf("Unknown problem type '%s'!\n", problem_type);
		exit(-1);
	}

	P->readConfig(problem);
	P->prepare();
	if (P->isTimeDependent())
	{
		P->tSolve(1.0);
	}
	else
	{
		P->nlSolve(1.0);
		P->saveSolution();
		P->saveVTKview();
//		P->calculateToF();
	}

	PetscFinalize();

	return 0;
}
